/*
compile:
cc svn_client_log.c -o svn_client_log  -I/usr/include/subversion-1 -I/usr/include/apr-1.0   -L/usr/lib   -lsvn_client-1 -lapr-1 -laprutil-1

run: 
./svn_client_log svn+ssh://ppquang@rd.anevia.com/svn/testing

*/

#include "svn_client.h"
#include "svn_cmdline.h"
#include "svn_pools.h"
#include "svn_config.h"
#include "svn_fs.h"

svn_error_t* sslserverprompt(svn_auth_cred_ssl_server_trust_t **cred_p, void * baton, 
								  const char * realm, apr_uint32_t failures, 
								  const svn_auth_ssl_server_cert_info_t * cert_info, 
								  svn_boolean_t may_save, apr_pool_t *pool)
{
	*cred_p = (svn_auth_cred_ssl_server_trust_t*)apr_pcalloc (pool, sizeof (**cred_p));
	(*cred_p)->may_save = FALSE;
	return SVN_NO_ERROR;
}

/* Display a prompt and read a one-line response into the provided buffer,
   removing a trailing newline if present. */
static svn_error_t *
prompt_and_read_line(const char *prompt,
                     char *buffer,
                     size_t max)
{
  int len;
  printf("%s: ", prompt);
  if (fgets(buffer, max, stdin) == NULL)
    return svn_error_create(0, NULL, "error reading stdin");
  len = strlen(buffer);
  if (len > 0 && buffer[len-1] == '\n')
    buffer[len-1] = 0;
  return SVN_NO_ERROR;
}

/* A tiny callback function of type 'svn_auth_simple_prompt_func_t'. For
   a much better example, see svn_cl__auth_simple_prompt in the official
   svn cmdline client. */
static svn_error_t *
my_simple_prompt_callback (svn_auth_cred_simple_t **cred,
                           void *baton,
                           const char *realm,
                           const char *username,
                           svn_boolean_t may_save,
                           apr_pool_t *pool)
{
  svn_auth_cred_simple_t *ret = apr_pcalloc (pool, sizeof (*ret));
  char answerbuf[100];

  if (realm)
    {
      printf ("Authentication realm: %s\n", realm);
    }

  if (username)
    ret->username = apr_pstrdup (pool, username);
  else
    {
      SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf)));
      ret->username = apr_pstrdup (pool, answerbuf);
    }

  SVN_ERR (prompt_and_read_line("Password", answerbuf, sizeof(answerbuf)));
  ret->password = apr_pstrdup (pool, answerbuf);

  *cred = ret;
  return SVN_NO_ERROR;
}


/* A tiny callback function of type 'svn_auth_username_prompt_func_t'. For
   a much better example, see svn_cl__auth_username_prompt in the official
   svn cmdline client. */
static svn_error_t *
my_username_prompt_callback (svn_auth_cred_username_t **cred,
                             void *baton,
                             const char *realm,
                             svn_boolean_t may_save,
                             apr_pool_t *pool)
{
  svn_auth_cred_username_t *ret = apr_pcalloc (pool, sizeof (*ret));
  char answerbuf[100];

  if (realm)
    {
      printf ("Authentication realm: %s\n", realm);
    }

  SVN_ERR (prompt_and_read_line("Username", answerbuf, sizeof(answerbuf)));
  ret->username = apr_pstrdup (pool, answerbuf);

  *cred = ret;
  return SVN_NO_ERROR;
}

//get log callback
static void iterate_hashtab(apr_hash_t *ht)
{
    apr_hash_index_t *hi;
    for (hi = apr_hash_first(NULL, ht); hi; hi = apr_hash_next(hi)) {
        const char *k;
        const char *v;
        
        apr_hash_this(hi, (const void**)&k, NULL, (void**)&v);
        printf("\t%s %s\n", v, k);
    }
}
static svn_error_t * my_log_msg_receiver_func(void *baton, apr_hash_t *changed_paths, svn_revnum_t revision, const char *author, const char *date,const char *message, apr_pool_t *pool)
{
    printf("------------------------------------------------------------------------\n");
    printf("%d | %s | %s | \n", (int)revision, author, date);
    printf("Changed paths:\n");
    if (changed_paths != NULL){
        iterate_hashtab(changed_paths);
    }
    printf("\n");
    printf("%s \n", message);
    printf("\n");
    return SVN_NO_ERROR;
}

int
main (int argc, const char **argv)
{
  apr_pool_t *pool;
  svn_error_t *err;
  svn_opt_revision_t revision;
  apr_hash_t *dirents;
  apr_hash_index_t *hi;
  svn_client_ctx_t *ctx;
  const char *URL;

  if (argc <= 1)
    {
      printf ("Usage:  %s URL\n", argv[0]);
      return EXIT_FAILURE;
    }
  else
    URL = argv[1];

  if (svn_cmdline_init ("minimal_client", stderr) != EXIT_SUCCESS)
    return EXIT_FAILURE;

  pool = svn_pool_create (NULL);

  err = svn_fs_initialize (pool);
  if (err)
    {
      svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
      return EXIT_FAILURE;
    }

  /* All clients need to fill out a client_ctx object. */
  {
    if ((err = svn_client_create_context (&ctx, pool)))
    {
        svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
        return EXIT_FAILURE;
    }

    if ((err = svn_config_get_config (&(ctx->config), NULL, pool)))
    {
        svn_handle_error2 (err, stderr, FALSE, "minimal_client: ");
        return EXIT_FAILURE;
    }

    {
      svn_auth_provider_object_t *provider;
      apr_array_header_t *providers = apr_array_make (pool, 4, sizeof (svn_auth_provider_object_t *));

      svn_auth_get_simple_prompt_provider (&provider, my_simple_prompt_callback, NULL,2, pool);
      APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;

      svn_auth_get_username_prompt_provider (&provider, my_username_prompt_callback, NULL, 2, pool);
      APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
      
      svn_auth_get_ssl_server_trust_file_provider (&provider, pool);
      APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;
      svn_auth_get_ssl_server_trust_prompt_provider (&provider, sslserverprompt, NULL, pool);
      APR_ARRAY_PUSH (providers, svn_auth_provider_object_t *) = provider;

      svn_auth_open (&ctx->auth_baton, providers, pool);
      svn_auth_set_parameter(&ctx->auth_baton, SVN_AUTH_PARAM_NON_INTERACTIVE, "");
      svn_auth_set_parameter(&ctx->auth_baton, SVN_AUTH_PARAM_DONT_STORE_PASSWORDS, "");
      svn_auth_set_parameter(&ctx->auth_baton, SVN_AUTH_PARAM_NO_AUTH_CACHE, "");
    }
  } /* end of client_ctx setup */

   svn_opt_revision_t start;
   svn_opt_revision_t end;
   start.kind = svn_opt_revision_head;
   end.kind = svn_opt_revision_number;
   end.value.number = 1;
   apr_pool_t *mp;
   apr_array_header_t *arr;     
   apr_initialize();
   apr_pool_create(&mp, NULL);
   arr = apr_array_make(mp, 32, sizeof(const char*));
   *(const char**)apr_array_push(arr) = URL;
   //svn_repos_get_logs(arr,NULL, svn_opt_revision_head, 1,TRUE,TRUE,my_log_msg_receiver_func,NULL, pool);
   //svn_client_log4(arr, NULL, &start, &end, 0, TRUE, TRUE, TRUE, NULL, NULL, NULL, ctx, pool);
   svn_client_log(arr, &start, &end, TRUE, FALSE, my_log_msg_receiver_func, NULL, ctx, pool);

  return EXIT_SUCCESS;
}
